package com.amazon.trietree.zkStub;

import com.amazon.trietree.db.PostgreUtils;
import com.amazon.trietree.server.MetaDataServerID;
import com.netflix.curator.framework.CuratorFramework;
import com.netflix.curator.framework.recipes.leader.LeaderSelector;
import com.netflix.curator.framework.recipes.leader.LeaderSelectorListener;
import org.apache.zookeeper.CreateMode;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Tylaar
 * Date: 11/9/12
 * Time: 11:04 AM
 * Company: Amazon.com
 */
public class CuratorClientStub {
    private String zkAddress;
    private String namespace;
    private int retryTimes;
    private int retryMargin;
    private int timeout;

    private String regDirectory;
    private String leaderDirectory;

    private MetaDataServerID id;
    //private PostgreUtils postgreUtils;
    private CuratorFramework clientStub;
    private CuratorLeaderSelector leaderSelector;

    public String getZkAddress() {
        return zkAddress;
    }

    public void setZkAddress(String zkAddress) {
        this.zkAddress = zkAddress;
    }

    public String getNamespace() {
        return namespace;
    }
    public String getLeaderDirectory() {
        return leaderDirectory;
    }

    public void setLeaderDirectory(String leaderDirectory) {
        this.leaderDirectory = leaderDirectory;
    }

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    public int getRetryTimes() {
        return retryTimes;
    }

    public void setRetryTimes(int retryTimes) {
        this.retryTimes = retryTimes;
    }

    public int getRetryMargin() {
        return retryMargin;
    }

    public void setRetryMargin(int retryMargin) {
        this.retryMargin = retryMargin;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public CuratorLeaderSelector getLeaderSelector() {
        return leaderSelector;
    }

    public void setLeaderSelector(CuratorLeaderSelector leaderSelector) {
        this.leaderSelector = leaderSelector;
    }

    public MetaDataServerID getId() {
        return id;
    }

    public void setId(MetaDataServerID id) {
        this.id = id;
    }

    public String getRegDirectory() {
        return regDirectory;
    }

    public void setRegDirectory(String regDirectory) {
        this.regDirectory = regDirectory;
    }


    public CuratorFramework getClientStub() {
        return clientStub;
    }

    public void setClientStub(CuratorFramework clientStub) {
        this.clientStub = clientStub;
    }

    public void init()throws Exception{
        this.setClientStub(CuratorClientFactory.createCuratorClientFactory(zkAddress,namespace,timeout,retryTimes,retryMargin));
        //this.setId(new MetaDataServerID(postgreUtils.getNextVal().toString()));
        this.setLeaderSelector(new CuratorLeaderSelector(clientStub, leaderDirectory, id.getPersonalID()));
        this.clientStub.start();
    }

    public void destroy()throws  Exception{
        clientStub.close();
        leaderSelector.close();
        //postgreUtils.closeConnection();
    }

    public void registerSelf() throws Exception {
        String regisPath = this.regDirectory + "/" + this.id.getPersonalID();
        clientStub.create().withMode(CreateMode.EPHEMERAL).forPath(regisPath, new byte[0]);
    }

    public void competeForMaster() throws IOException {
        Thread t = new Thread(new CuratorLeaderThread(getLeaderSelector()));
        t.run();
    }

    public void stopCompeteForMaster() throws IOException{
        leaderSelector.close();
    }
}
